/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Initial Developer of the Original Code is
*   Nick Kreeger
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Nick Kreeger <nick.kreeger@park.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#import "CHMsgComposeWindow.h"

#import "Attachment.h"
#import "NSString+Utils.h"

#import "nsMsgBaseCID.h"
#import "nsMsgCompCID.h"
#import "CHMsgUtils.h"
#import "nsIMsgSend.h"
#import "nsIMsgAttachment.h"
#import "nsIMsgMailSession.h"
#import "nsIDOMWindow.h"

class CHMsgComposeStateListener : public nsIMsgComposeStateListener
{
public:
  CHMsgComposeStateListener(CHMsgComposeWindow* aMsgComposeWindow);
  virtual ~CHMsgComposeStateListener();
  
  NS_DECL_ISUPPORTS
  NS_DECL_NSIMSGCOMPOSESTATELISTENER
    
private:
   CHMsgComposeWindow* mComposeWindow;  // weak
};

/**
 * This interface doesn't work on the 1.8 branch, but is here
 * for future compatibility.
 */
class CHMsgSendListener : public nsIMsgSendListener
{
public:
  CHMsgSendListener(CHMsgComposeWindow* aMsgComposeWindow);
  virtual ~CHMsgSendListener();
  
  NS_DECL_ISUPPORTS
  NS_DECL_NSIMSGSENDLISTENER
    
private:
  CHMsgComposeWindow* mComposeWindow;  // weak
};


class CHMsgProgress : public nsIMsgProgress
{
public:
  CHMsgProgress(CHMsgComposeWindow* aMsgComposeWindow);
  virtual ~CHMsgProgress();
  
  NS_DECL_ISUPPORTS
  NS_DECL_NSIMSGPROGRESS
  NS_DECL_NSIWEBPROGRESSLISTENER
    
private:
  CHMsgComposeWindow* mComposeWindow;  // weak
};


NS_IMPL_ISUPPORTS0(CHMsgComposeWindow);

CHMsgComposeWindow::CHMsgComposeWindow()
{
  mMsgCompose = nsnull;
  mMsgComposeParams = nsnull;
  mQuote = nsnull;
  mIdentity = nsnull;
  mQuotingOutputStreamListener = nsnull;
  mMsgWindow = nsnull;
  mListenerDelegate = nil;
}

CHMsgComposeWindow::~CHMsgComposeWindow()
{
  NS_IF_RELEASE(mQuotingOutputStreamListener);
  NS_IF_RELEASE(mMsgComposeStateListener);
  NS_IF_RELEASE(mMsgSendListener);
  NS_IF_RELEASE(mMsgProgress);
}

void 
CHMsgComposeWindow::Initialize(nsIMsgComposeParams* aMsgComposeParams,
                               id<ComposerStateListenerDelegate> aListenerDelegate,
                               CHBrowserView* aBrowserView)
{
  nsresult rv;
  mListenerDelegate = aListenerDelegate;
  
  rv = aMsgComposeParams->GetIdentity(getter_AddRefs(mIdentity));
  if (NS_FAILED(rv))
    return;
  
  mMsgCompose = do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv);
  if (NS_FAILED(rv))
    return;
  
  mMsgComposeStateListener = new CHMsgComposeStateListener(this);
  mMsgSendListener = new CHMsgSendListener(this);
  mMsgProgress = new CHMsgProgress(this);
  
  NS_IF_ADDREF(mMsgComposeStateListener);
  NS_IF_ADDREF(mMsgSendListener);
  NS_IF_ADDREF(mMsgProgress);
  
  mMsgCompose->RegisterStateListener(mMsgComposeStateListener);
  
  MSG_ComposeType compType;
  aMsgComposeParams->GetType(&compType);
  
  mMsgCompose->SetType(compType);
  
  nsCOMPtr<nsIDOMWindow> domWindow = [aBrowserView getContentWindow];
  if (domWindow)
  {
    nsCOMPtr<nsIDOMWindowInternal> internalDom = do_QueryInterface(domWindow);
    rv = mMsgCompose->Initialize(internalDom, aMsgComposeParams);
    
    mMsgWindow = do_CreateInstance(NS_MSGWINDOW_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv))
    {
      mMsgWindow->SetDOMWindow(internalDom);
      
      nsCOMPtr<nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
      if (NS_SUCCEEDED(rv))
        mailSession->AddMsgWindow(mMsgWindow);
    }
  }
  
  NS_IF_ADDREF(aMsgComposeParams);
  mMsgComposeParams = aMsgComposeParams;
  
  // If this is a new message, just show the window.
  if (compType == nsIMsgCompType::New)
  {
    [mListenerDelegate onComposeFieldsReady];
    [mListenerDelegate showComposeWindow];
  }
  
  if (compType == nsIMsgCompType::Reply ||
      compType == nsIMsgCompType::ReplyAll ||
      compType == nsIMsgCompType::ReplyToSender ||
      compType == nsIMsgCompType::ForwardInline)
  {
    mQuote = do_CreateInstance(NS_MSGQUOTE_CONTRACTID, &rv);
    if (NS_FAILED(rv) || !mQuote)
      return;
    
    PRBool bAutoQuote = PR_TRUE;
    mIdentity->GetAutoQuote(&bAutoQuote);
    
    nsXPIDLCString originalUri;
    aMsgComposeParams->GetOriginalMsgURI(getter_Copies(originalUri));
    
    nsCOMPtr<nsIMsgDBHdr> originalMsgHdr;
    rv = GetMsgDBHdrFromURI(originalUri, getter_AddRefs(originalMsgHdr));
    if (NS_FAILED(rv))
      return;
    
    // This ref will get released when the nsMsgQuote is released.
    mQuotingOutputStreamListener = new
      CHQuotingOutputStreamListener(originalUri, originalMsgHdr, 
                                    PR_FALSE,    // quote headers 
                                    !bAutoQuote, // headers only
                                    mIdentity,
                                    (compType == nsIMsgCompType::ForwardInline), // is forward inline?
                                    "",          // quote charset
                                    PR_FALSE,    // charet override
                                    PR_TRUE);    // quote original
                                    
    NS_ADDREF(mQuotingOutputStreamListener);
                                
    mQuotingOutputStreamListener->SetComposeObject(mMsgCompose);
    rv = mQuote->QuoteMessage(originalUri.get(), PR_FALSE, mQuotingOutputStreamListener, "", !bAutoQuote);
#if DEBUG
    if (NS_FAILED(rv))
      printf("Could not quote... : %ui", rv);
#endif
  }
}

void 
CHMsgComposeWindow::SendMessage()
{
  nsCOMPtr<nsIMsgIdentity> identity;
  mMsgComposeParams->GetIdentity(getter_AddRefs(identity));
  
  // This is broken, so lets work around it with the nsIMsgProgress interface for now.
  /*
   CHMsgSendListener* sendListener = new CHMsgSendListener();
   sendListener->SetProgressDelegate(self);
   mMsgComposeParams->SetSendListener(sendListener);
   */
  
  //mMsgComposeParams->SetSendListener(this);
  mMsgCompose->SendMsg(nsIMsgSend::nsMsgDeliverNow, identity, 
                       nsnull,  // accountKey
                       nsnull,  // msgWindow, don't add this because the window will
                                // get destroyed before we want it to.
                       mMsgProgress);   // nsIMsgProgress
}

void
CHMsgComposeWindow::AbortSend()
{
  mMsgCompose->Abort();
}

void
CHMsgComposeWindow::WindowWillClose()
{
  // Perform any cleanup.
  nsCOMPtr<nsIMsgComposeStateListener> sendListener = do_QueryInterface(mMsgSendListener);
  mMsgCompose->UnregisterStateListener(sendListener);
  
  mMsgWindow->CloseWindow();
  
  nsresult rv;
  nsCOMPtr<nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
  if (NS_SUCCEEDED(rv))
    rv = mailSession->RemoveMsgWindow(mMsgWindow);
}

void 
CHMsgComposeWindow::OnComposeBodyReady()
{
  NSString* bodyText = nil;
  
  if (mQuotingOutputStreamListener)
    if (NS_FAILED(mQuotingOutputStreamListener->GetBodyText(&bodyText)))
      return;
  
  [mListenerDelegate onComposeBodyReady:bodyText];
}

NSString* 
CHMsgComposeWindow::GetToLiteral()
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return @"";
  
  nsAutoString toStr;
  rv = compFields->GetTo(toStr);
  NS_ENSURE_SUCCESS(rv, @"");
  
  return [NSString stringWith_nsAString:toStr];
}

NSString* 
CHMsgComposeWindow::GetCcLiteral()
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return @"";
  
  nsAutoString ccStr;
  rv = compFields->GetCc(ccStr);
  NS_ENSURE_SUCCESS(rv, @"");
  
  return [NSString stringWith_nsAString:ccStr];
}

NSString* 
CHMsgComposeWindow::GetSubject()
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return @"";
  
  nsAutoString subjectStr;
  rv = compFields->GetSubject(subjectStr);
  NS_ENSURE_SUCCESS(rv, @"");
  
  return [NSString stringWith_nsAString:subjectStr];
}

NSString* 
CHMsgComposeWindow::GetBodyLiteral()
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return @"";
  
  nsAutoString bodyStr;
  rv = compFields->GetBody(bodyStr);
  NS_ENSURE_SUCCESS(rv, @"");
  
  return [NSString stringWith_nsAString:bodyStr];
}

void 
CHMsgComposeWindow::SetToLiteral(NSString* inToField)
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  nsAutoString toString;
  [inToField assignTo_nsAString:toString];
  compFields->SetTo(toString);
}

void 
CHMsgComposeWindow::SetCcLiteral(NSString* inCcField)
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  nsAutoString ccString;
  [inCcField assignTo_nsAString:ccString];
  compFields->SetCc(ccString);
}

void 
CHMsgComposeWindow::SetSubject(NSString* inSubjectField)
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  nsAutoString subjectString;
  [inSubjectField assignTo_nsAString:subjectString];
  compFields->SetSubject(subjectString);
}

void 
CHMsgComposeWindow::SetBodyLiteral(NSString* inBodyField)
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  // Make sure there is a newline at the end of the body
  if (![inBodyField isEqualToString:@""] && [inBodyField characterAtIndex:([inBodyField length] - 1)] != '\n')
    inBodyField = [inBodyField stringByAppendingString:@"\n"];
  
  nsAutoString bodyString;
  [inBodyField assignTo_nsAString:bodyString];
  compFields->SetBody(bodyString);
}

void
CHMsgComposeWindow::SetForcePlainText(BOOL inShouldForcePlainText)
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  compFields->SetForcePlainText(inShouldForcePlainText);
}

void 
CHMsgComposeWindow::AddAttachment(NSURL* aUrl)
{
  if (!aUrl)
    return;
  
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return;
  
  nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv);
  if (NS_FAILED(rv) || !attachment)
    return;
  
  // CLEAN THIS UP:
  // |SetUrl| will set the name of the attachment
  attachment->SetUrl([[@"file://" stringByAppendingString:[aUrl path]] cString]);
  compFields->AddAttachment(attachment);
}

id<ComposerStateListenerDelegate> 
CHMsgComposeWindow::GetComposerStateListener()
{
  return mListenerDelegate;
}

nsresult 
CHMsgComposeWindow::GetMsgWindow(nsIMsgWindow** aMsgWindow)
{
  NS_IF_ADDREF(*aMsgWindow = mMsgWindow);
  return NS_OK;
}

void 
CHMsgComposeWindow::RemoveAttachment(NSURL* aUrl)
{
}

NSArray*
CHMsgComposeWindow::GetAttachmentArray()
{
  nsresult rv;
  nsCOMPtr<nsIMsgCompFields> compFields;
  rv = mMsgComposeParams->GetComposeFields(getter_AddRefs(compFields));
  if (NS_FAILED(rv) || !compFields)
    return nil;
  
  nsCOMPtr<nsISupportsArray> attachmentArray;
  rv = compFields->GetAttachmentsArray(getter_AddRefs(attachmentArray));
  if (NS_FAILED(rv) || !attachmentArray)
    return nil;
  
  PRUint32 arrSize, i;
  rv = attachmentArray->Count(&arrSize);
  if (NS_FAILED(rv) || arrSize == 0)
    return nil;
  
  NSMutableArray* attachArray = [NSMutableArray array];
  
  for (i = 0; i < arrSize; i++)
  {
    nsCOMPtr<nsISupports> supportsVal = attachmentArray->ElementAt(i);
    if (!supportsVal)
      continue;
    
    nsCOMPtr<nsIMsgAttachment> attachment = do_QueryInterface(supportsVal);
    if (!attachment)
      continue;
    
    // For now, just add the display name of each attachment, this needs to
    // be reworked to work with the composition attachment object |nsIMsgAttachment|.
    //
    // To get the display name, we have to generate it from the URL of the attachment:
    nsXPIDLCString attachUrl;
    if (NS_SUCCEEDED(attachment->GetUrl(getter_Copies(attachUrl))))
    {
      NSString* urlString = [NSString stringWithCString:attachUrl];
      Attachment* curAttachment = [[Attachment alloc] init];
      [curAttachment setDisplayName:[urlString lastPathComponent]];
      [attachArray addObject:curAttachment];
      [curAttachment release];
    }
  }
  
  return attachArray;
}

#pragma mark -

NS_IMPL_ISUPPORTS1(CHMsgComposeStateListener, nsIMsgComposeStateListener);

CHMsgComposeStateListener::CHMsgComposeStateListener(CHMsgComposeWindow* aMsgComposeWindow)
{
   mComposeWindow = aMsgComposeWindow;
}

CHMsgComposeStateListener::~CHMsgComposeStateListener()
{
  mComposeWindow = nsnull;
}

NS_IMETHODIMP
CHMsgComposeStateListener::NotifyComposeFieldsReady()
{
  [mComposeWindow->GetComposerStateListener() onComposeFieldsReady];
  return NS_OK;
}

NS_IMETHODIMP
CHMsgComposeStateListener::NotifyComposeBodyReady()
{
  mComposeWindow->OnComposeBodyReady();
  return NS_OK;
}

NS_IMETHODIMP
CHMsgComposeStateListener::ComposeProcessDone(nsresult aResult)
{
  if (NS_SUCCEEDED(aResult))
      [mComposeWindow->GetComposerStateListener() onComposeProcessDone];
  
#if DEBUG
  NSLog(@"CHMsgComposeStateListener::ComposeProcessDone: %i", aResult);
#endif
  return NS_OK;
}

NS_IMETHODIMP
CHMsgComposeStateListener::SaveInFolderDone(const char *folderName)
{
  [mComposeWindow->GetComposerStateListener() onSaveInFolderDone:[NSString stringWithCString:folderName]];
  
#if DEBUG
  NSLog(@"CHMsgComposeStateListener::SaveInFolderDone = %s", folderName);
#endif
  return NS_OK;
}

#pragma mark -

NS_IMPL_ISUPPORTS1(CHMsgProgress, nsIMsgProgress);

CHMsgProgress::CHMsgProgress(CHMsgComposeWindow* aMsgComposeWindow)
{
  mComposeWindow = aMsgComposeWindow;
}

CHMsgProgress::~CHMsgProgress()
{
  mComposeWindow = nsnull;
}

NS_IMETHODIMP 
CHMsgProgress::OpenProgressDialog(nsIDOMWindowInternal* parent, nsIMsgWindow* aMsgWindow, const char* dialogURL, nsISupports* parameters)
{
  [mComposeWindow->GetComposerStateListener() showProgressDialog];
  
#if DEBUG
  NSLog(@"CHMsgComposeWindow::OpenProgressDialog");
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::CloseProgressDialog(PRBool forceClose)
{
  [mComposeWindow->GetComposerStateListener() closeProgressDialog];
  
#if DEBUG
  NSLog(@"CHMsgComposeWindow::CloseProgressDialog");
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::RegisterListener(nsIWebProgressListener* listener)
{
#if DEBUG
  NSLog(@"RegisterLiseneter...");
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::UnregisterListener(nsIWebProgressListener* listener)
{
#if DEBUG
  NSLog(@"UnregisterListener...");
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::GetPrompter(nsIPrompt** aRetVal)
{
#if DEBUG
  NSLog(@"GetPrompter");
#endif
  nsresult rv;
  nsCOMPtr<nsIMsgWindow> msgWindow;
  rv = mComposeWindow->GetMsgWindow(getter_AddRefs(msgWindow));
  if (NS_FAILED(rv) || !msgWindow)
    return NS_ERROR_FAILURE;
  
  nsCOMPtr<nsIPrompt> prompt;
  rv = msgWindow->GetPromptDialog(getter_AddRefs(prompt));
  if (NS_SUCCEEDED(rv))
    NS_IF_ADDREF(*aRetVal = prompt);

  return (prompt) ? NS_OK : NS_ERROR_FAILURE;
}

NS_IMETHODIMP 
CHMsgProgress::GetProcessCanceledByUser(PRBool* aProcessCanceledByUser)
{
  //XXX write me!
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::SetProcessCanceledByUser(PRBool aProcessCanceledByUser)
{
  //XXX write me!
  return NS_OK;
}

//XXX implement these functions to get the sheet so span from the composer window
NS_IMETHODIMP 
CHMsgProgress::GetMsgWindow(nsIMsgWindow* * aMsgWindow)
{
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::SetMsgWindow(nsIMsgWindow*  aMsgWindow)
{
  return NS_OK;
}

NS_IMETHODIMP
CHMsgProgress::OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, PRUint32 aStateFlags, nsresult aStatus)
{
#if DEBUG
  NSLog(@"OnStateChange::");
#endif
  /*
  if (aStateFlags == nsIWebProgressListener::STATE_START)
    [mListenerDelegate onStartSending];
  */
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::OnProgressChange(nsIWebProgress* aWebProgress, 
                                nsIRequest* aRequest, 
                                PRInt32 aCurSelfProgress, 
                                PRInt32 aMaxSelfProgress, 
                                PRInt32 aCurTotalProgress, 
                                PRInt32 aMaxTotalProgress)
{
#if DEBUG
  NSLog(@"OnProgressChange: cur=%i max=%i curT=%i maxT=%i", 
        aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::OnLocationChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, nsIURI* aLocation)
{
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgProgress::OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, nsresult aStatus, const PRUnichar* aMessage)
{
  NSString* str = [NSString stringWithFormat:@"::OnStatusChange() --> %@", [NSString stringWithPRUnichars:aMessage]];
  [mComposeWindow->GetComposerStateListener() onStatus:[NSString stringWithPRUnichars:aMessage]];
#if DEBUG
  NSLog(@"OnStatusChange: %@", str);
#endif
  return NS_OK;
}

NS_IMETHODIMP
CHMsgProgress::OnSecurityChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, PRUint32 aState)
{
  return NS_OK;
}

#pragma mark -

/**
 * This interface doesn't work on the 1.8 branch, but is here
 * for future compatibility.
 */
NS_IMPL_ISUPPORTS1(CHMsgSendListener, nsIMsgSendListener);

CHMsgSendListener::CHMsgSendListener(CHMsgComposeWindow* aMsgComposeWindow)
{
  mComposeWindow = aMsgComposeWindow;
}

CHMsgSendListener::~CHMsgSendListener()
{
  mComposeWindow = nsnull;
}

NS_IMETHODIMP 
CHMsgSendListener::OnStartSending(const char *aMsgID, PRUint32 aMsgSize)
{
#if DEBUG
  NSLog(@"OnStartSending: %s, %ui", aMsgID, aMsgSize);
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgSendListener::OnProgress(const char *aMsgID, PRUint32 aProgress, PRUint32 aProgressMax)
{
#if DEBUG
  NSLog(@"OnProgress: %s, %ui, %ui", aMsgID, aProgress, aProgressMax);
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgSendListener::OnStatus(const char *aMsgID, const PRUnichar *aMsg)
{
#if DEBUG
  NSLog(@"OnStatus: %s, %@", aMsgID, [NSString stringWithPRUnichars:aMsg]);
#endif
  return NS_OK;
}

NS_IMETHODIMP
CHMsgSendListener::OnStopSending(const char *aMsgID, nsresult aStatus, const PRUnichar *aMsg, nsIFileSpec *returnFileSpec)
{
#if DEBUG
  NSLog(@"OnStopSending: %s, %ui, %@", aMsgID, aStatus, [NSString stringWithPRUnichars:aMsg]); 
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgSendListener::OnGetDraftFolderURI(const char *aFolderURI)
{
#if DEBUG
  NSLog(@"OnGetDraftFolderURI: %s", aFolderURI);
#endif
  return NS_OK;
}

NS_IMETHODIMP 
CHMsgSendListener::OnSendNotPerformed(const char *aMsgID, nsresult aStatus)
{
#if DEBUG
  NSLog(@"OnSendNotPerformed: %s, %ui", aMsgID, aStatus);
#endif
  return NS_OK;
}
